package main

import (
	"fmt"
	"math/rand"
	"time"
)

/**
*  User: zhanbei
*  Date: 2025/10/27
*  Description: 黑客帝国数字雨特效 - Matrix风格的字符流淌效果
 */

// MatrixColumn 表示一列数字雨
type MatrixColumn struct {
	x          int    // 列的x坐标
	y          int    // 当前头部的y坐标
	length     int    // 雨滴的长度
	speed      int    // 速度（每次更新移动的行数）
	chars      []rune // 这一列的字符
	brightness []int  // 每个字符的亮度
	maxY       int    // 最大y坐标
	active     bool   // 是否活跃
	delay      int    // 延迟启动
}

// 可用的字符集（包括数字、字母、日文片假名、特殊符号）
var matrixChars = []rune{
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
	'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
	'ﾊ', 'ﾐ', 'ﾋ', 'ｰ', 'ｳ', 'ｼ', 'ﾅ', 'ﾓ', 'ﾆ', 'ｻ', 'ﾜ', 'ﾂ', 'ｵ', 'ﾘ',
	'ｱ', 'ﾎ', 'ﾃ', 'ﾏ', 'ｹ', 'ﾒ', 'ｴ', 'ｶ', 'ｷ', 'ﾑ', 'ﾕ', 'ﾗ', 'ｾ', 'ﾈ',
	'ｽ', 'ﾀ', 'ﾇ', 'ﾍ', ':', '・', '.', '=', '*', '+', '-', '<', '>', '¦', '|',
}

// 创建新的数字雨列
func newMatrixColumn(x, maxY int) *MatrixColumn {
	length := rand.Intn(15) + 5 // 长度5-20
	speed := rand.Intn(2) + 1   // 速度1-2

	col := &MatrixColumn{
		x:          x,
		y:          -length,
		length:     length,
		speed:      speed,
		chars:      make([]rune, length),
		brightness: make([]int, length),
		maxY:       maxY,
		active:     false,
		delay:      rand.Intn(50), // 随机延迟0-50帧
	}

	// 初始化字符
	for i := 0; i < length; i++ {
		col.chars[i] = matrixChars[rand.Intn(len(matrixChars))]
	}

	// 设置亮度（头部最亮，尾部逐渐变暗）
	for i := 0; i < length; i++ {
		if i == 0 {
			col.brightness[i] = 3 // 最亮（白色）
		} else if i < 3 {
			col.brightness[i] = 2 // 亮绿色
		} else if i < 6 {
			col.brightness[i] = 1 // 绿色
		} else {
			col.brightness[i] = 0 // 暗绿色
		}
	}

	return col
}

// 更新列的位置
func (col *MatrixColumn) update() {
	if !col.active {
		col.delay--
		if col.delay <= 0 {
			col.active = true
		}
		return
	}

	col.y += col.speed

	// 随机改变某些字符
	if rand.Float64() < 0.3 {
		idx := rand.Intn(col.length)
		col.chars[idx] = matrixChars[rand.Intn(len(matrixChars))]
	}
}

// 绘制列
func (col *MatrixColumn) draw() {
	if !col.active {
		return
	}

	for i := 0; i < col.length; i++ {
		charY := col.y - i
		if charY > 0 && charY <= col.maxY {
			moveCursor(col.x, charY)

			// 根据亮度设置颜色
			switch col.brightness[i] {
			case 3:
				setColor(97) // 亮白色（头部）
			case 2:
				setColor(92) // 亮绿色
			case 1:
				setColor(32) // 绿色
			case 0:
				setColor(90) // 暗绿色（几乎看不见）
			}

			fmt.Print(string(col.chars[i]))
		}
	}
}

// 清除列
func (col *MatrixColumn) clear() {
	if !col.active {
		return
	}

	for i := 0; i < col.length; i++ {
		charY := col.y - i
		if charY > 0 && charY <= col.maxY {
			moveCursor(col.x, charY)
			fmt.Print(" ")
		}
	}
}

// 检查是否已经完全离开屏幕
func (col *MatrixColumn) isOffScreen() bool {
	return col.active && (col.y-col.length) > col.maxY
}

// RunHack 黑客帝国数字雨特效
func RunHack() {
	rand.Seed(time.Now().UnixNano())

	width, height := getTerminalSize()

	// 隐藏光标
	hideCursor()
	defer showCursor()

	// 清屏
	clearScreen()

	// 设置背景为黑色
	fmt.Print("\033[40m")
	defer resetColor()

	// 显示标题
	moveCursor(width/2-20, 1)
	setColor(92) // 亮绿色
	fmt.Print("▓▒░ WELCOME TO THE MATRIX ░▒▓")
	resetColor()

	moveCursor(width/2-15, 2)
	setColor(32)
	fmt.Print("Press Ctrl+C to disconnect...")
	resetColor()

	// 创建数字雨列（每一列都有）
	columns := make([]*MatrixColumn, 0)
	for x := 1; x <= width; x++ {
		col := newMatrixColumn(x, height)
		columns = append(columns, col)
	}

	// 设置超时
	done := make(chan bool)
	go func() {
		time.Sleep(60 * time.Second)
		done <- true
	}()

	// 动画主循环
	ticker := time.NewTicker(50 * time.Millisecond)
	defer ticker.Stop()

	// 开场动画：显示一些经典的黑客帝国文本
	showMatrixIntro(width, height)

	// 清屏准备数字雨
	clearScreen()

loop:
	for {
		select {
		case <-done:
			break loop
		case <-ticker.C:
			// 更新所有列
			newColumns := make([]*MatrixColumn, 0)
			for _, col := range columns {
				// 清除旧位置
				col.clear()

				// 更新位置
				col.update()

				// 绘制新位置
				col.draw()

				// 如果列已经离开屏幕，创建新的列
				if col.isOffScreen() {
					newCol := newMatrixColumn(col.x, height)
					newColumns = append(newColumns, newCol)
				} else {
					newColumns = append(newColumns, col)
				}
			}
			columns = newColumns

			resetColor()
		}
	}

	// 清屏并显示结束信息
	clearScreen()
	moveCursor(width/2-15, height/2-1)
	setColor(92)
	fmt.Println("▓▒░ DISCONNECTED ░▒▓")
	moveCursor(width/2-20, height/2+1)
	setColor(32)
	fmt.Println("The Matrix has you...")
	resetColor()
	moveCursor(1, height)
	time.Sleep(2 * time.Second)
}

// 显示黑客帝国风格的开场动画
func showMatrixIntro(width, height int) {
	messages := []string{
		"Wake up, Neo...",
		"The Matrix has you...",
		"Follow the white rabbit.",
		"Knock, knock, Neo.",
	}

	centerY := height / 2

	for _, msg := range messages {
		clearScreen()
		x := (width - len(msg)) / 2
		if x < 1 {
			x = 1
		}

		// 逐字符显示效果
		for i, ch := range msg {
			moveCursor(x+i, centerY)
			setColor(92)
			fmt.Print(string(ch))
			time.Sleep(50 * time.Millisecond)
		}
		time.Sleep(800 * time.Millisecond)
	}

	// 显示"初始化"效果
	clearScreen()
	moveCursor(width/2-10, centerY-1)
	setColor(92)
	fmt.Print("Initializing...")

	moveCursor(width/2-10, centerY)
	for i := 0; i < 20; i++ {
		fmt.Print("█")
		time.Sleep(50 * time.Millisecond)
	}

	time.Sleep(500 * time.Millisecond)
}
